package com.ktjiaoyu.springsecuritydemo.config;

import com.ktjiaoyu.springsecuritydemo.handle.MyAccessDeniedHandlerImpl;
import com.ktjiaoyu.springsecuritydemo.handle.MyForwardAuthenticationFailureHandler;
import com.ktjiaoyu.springsecuritydemo.handle.MyForwardAuthenticationSuccessHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import javax.sql.DataSource;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Resource
    UserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //改变默认的登录页面为我们自己的页面
        //会加上登录的过滤器
        http.formLogin()
                .loginPage("/toLogin") //设置登录页面路劲
                .loginProcessingUrl("/doLogin") //设置登录提交路劲
                .successForwardUrl("/toMain") //设置登录成功跳转路劲
                //登录成功跳转到外网路劲
//                .successHandler(new MyForwardAuthenticationSuccessHandler("http://www.baidu.com"))
                .failureForwardUrl("/toError");//设置登录失败跳转路劲
                //登录失败跳转到外网路劲
//                .failureHandler(new MyForwardAuthenticationFailureHandler("http://www.jd.com"));

        //授权
        http.authorizeRequests()
                .antMatchers("/toLogin").permitAll() //指定toLogin路劲任何人都可以访问
                .antMatchers("/css/**","/js/**").permitAll()
//                .antMatchers("/toMain1").hasAuthority("admin") //需要拥有admin权限才能访问
//                .antMatchers("/toMain1").hasAnyAuthority("admin","Admin","ADMIN") //只要拥有任意一个权限即访问
//                .antMatchers("/toMain1").hasRole("abc") //需要拥有abc角色才能访问
//                .antMatchers("/toMain1").hasAnyRole("abc","Abc","ABC") //只要拥有任意一个角色即可访问
                .anyRequest().authenticated();//剩余其他请求路劲都需要登录才能访问

        //不验证跨域问题
        http.csrf().disable();

        //异常处理
        http.exceptionHandling()
                .accessDeniedHandler(new MyAccessDeniedHandlerImpl());//权限不足的异常处理

        //配置退出登录 会加上退出的过滤器
        http.logout()
                .logoutSuccessUrl("/toLogin");//退出成功跳转到登录页面

        //记住我的配置
        http.rememberMe()
                .tokenRepository(getPersistentTokenRepository())
                .userDetailsService(userDetailsService)
                .tokenValiditySeconds(60);
    }

    @Resource
    private DataSource dataSource; // 数据源对象

    @Bean
    public PersistentTokenRepository getPersistentTokenRepository() {
        JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
        // 设置数据源对象
        jdbcTokenRepository.setDataSource(dataSource);
        // 设置保存[记住我]的用户信息的表，下面setCreateTableStartup(true)表示自动创建这张表
        // 需要注意的是：第一次启动的时候需要使用下面这行代码创建表，第二次启动时则要把这行代码注释掉
//        jdbcTokenRepository.setCreateTableOnStartup(true);
        return jdbcTokenRepository;
    }

}
